<template>
  <div class="main-content-box">
    <div id="container"></div>
  </div>
</template>

<script>
import G6 from '@antv/g6';
export default {
  name: 'g6demo7',
  data () {
    return {
      data: {
        randomColor: ''
      }
    }
  },
  mounted () {
    // this.randomColor = this.getRandomColor()
    setTimeout(() => {
      this.getInit()
    }, 100)
    // console.log(this.randomColor)
  },
  methods: {
    /**
     * 尝试新的实现方法
     */
    getInit () {

      const nodes = [];
      const edges = [];

      // 中心节点
      const centerNode = {
        id: 'center',
        x: 500,
        y: 300,
        // type: 'center-node',
        size: 66,
        label: '集团',
        text: '\ue827',  //对应iconfont.css 里面的content，注意加u
        style: {
          fill: 'red'
        },
        labelCfg: {
          style: {
            fill: "blue"
          }
        },
        backgroundConfig: null  // 自定义项，用于判读是否需要圆背景
      };
      nodes.push(centerNode);

      // 左侧一级节点
      const leftMoudelNode = {
        id: 'node1',
        x: 350,
        y: 300,
        label: '光纤',
        text: '\ue719',
        style: {
          fill: 'Coral'
        },
        backgroundConfig: null,
        size: 45,
      }
      nodes.push(leftMoudelNode);
      edges.push({ source: 'node1', target: 'center', type: 'can-running' });
      let leftGzzNode = {

      }
      // 左侧添加 4 个节点
      for (let i = 0; i < 4; i++) {
        const id = 'left' + i;
        nodes.push({
          id,
          x: 150,
          y: (i + 1) * 100 + 50,
          type: 'leaf-node',
          text: '\ue60e',
          label: (i + 1) + '号楼',
          style: {
            fill: '#5B8FF9'
          },
          backgroundConfig: null,
          size: 45,
        });
        edges.push({ source: id, target: 'node1', type: 'can-running' });
      }
      for (let i = 0; i < 4; i++) {
        const id = 'leftNodeGzz' + i;
        nodes.push({
          id,
          x: 50,
          y: (i + 1) * 100 + 50,
          type: 'leaf-node',
          text: '\ue68c',
          label: '工作站',
          style: {
            fill: '#c6E5F5'
          },
          backgroundConfig: null,
          size: 45,
        });
        edges.push({ source: id, target: 'left' + i, type: 'can-running' });
      }
      // 右侧添加 5 个节点
      for (let i = 0; i < 5; i++) {
        const id = 'right' + i;
        const edgesId = 'edgeRight' + i
        nodes.push({
          id,
          x: 750,
          y: i * 100 + 50,
          type: 'leaf-node',
          text: '\ue60e',
          label: (i + 5) + '号楼',
          relation: '以太网',
          style: {
            fill: '#5B8FF9'
          },
          backgroundConfig: null,
          size: 45,
          linebackgroundConfig: {
            fill: 'Coral',
          },
        });
        edges.push({
          id: edgesId,
          source: 'center',
          target: id,
          type: 'can-running',
          label: id === 'right0' ? '高速宽带' : '以太网',
          style: {
            //  stroke: setInterval(() => {
            //    this.getRandomColor()
            //    console.log(this.getRandomColor())
            //  }, 1000),
            stroke: 'red'
          },
          labelCfg: {
            style: {
              fill: id === 'right0' ? 'Coral' : 'cyan'
            }
          }
        });
      }
      /* edges.push({
        id: 'edgeRight0',
        source: 'center',
        target: 'right0',
        type: 'can-running',
        label: '高速宽带',
        style: {
          stroke: 'red'
        },
        labelCfg: {
          style: {
            fill: 'Coral'
          }
        }
      });
      edges.push({
        id: 'edgeRight1',
        source: 'center',
        target: 'right1',
        type: 'can-running',
        label: '以太网',
        style: {
          stroke: 'red'
        },
        labelCfg: {
          style: {
            fill: 'cyan'
          }
        }
      });
      edges.push({
        id: 'edgeRight2',
        source: 'center',
        target: 'right2',
        type: 'can-running',
        label: '以太网',
        style: {
          stroke: 'red'
        },
        labelCfg: {
          style: {
            fill: 'cyan'
          }
        }
      });
      edges.push({
        id: 'edgeRight3',
        source: 'center',
        target: 'right3',
        type: 'can-running',
        label: '以太网',
        style: {
          stroke: 'red'
        },
        labelCfg: {
          style: {
            fill: 'cyan'
          }
        }
      });
      edges.push({
        id: 'edgeRight4',
        source: 'center',
        target: 'right4',
        type: 'can-running',
        label: '以太网',
        style: {
          stroke: 'red'
        },
        labelCfg: {
          style: {
            fill: 'cyan'
          }
        }
      }); */

      for (let i = 0; i < 5; i++) {
        const id = 'rightNodeGzz' + i;
        nodes.push({
          id,
          x: 950,
          y: (i + 1) * 100,
          type: 'leaf-node',
          text: '\ue68c',
          label: '工作站',
          style: {
            fill: '#c6E5F5'
          },
          backgroundConfig: null,
          size: 45,
        });
        edges.push({ source: 'right' + i, target: id, type: 'can-running' });
      }

      // edges.push({ source: 'rightNodeGzz0', target: 'rightNodeGzz1', type: 'can-running' });

      //
      G6.registerNode(
        'leaf-node',
        {
          draw (cfg, group) {
            const { backgroundConfig: backgroundStyle, style, labelCfg: labelStyle } = cfg;

            if (backgroundStyle) {
              group.addShape('circle', {
                attrs: {
                  x: 0,
                  y: 0,
                  r: cfg.size,
                  ...backgroundStyle,
                },
                // must be assigned in G6 3.3 and later versions. it can be any value you want
                name: 'circle-shape',
              });
            }
            group.addShape('circle', {
              attrs: {
                x: -120,
                y: 0,
                r: 30,
                ...backgroundStyle,
              },
              name: 'circle-shape',
            });
            const keyShape = group.addShape('text', {
              attrs: {
                x: 0,
                y: 0,
                fontFamily: 'iconfont', // 对应css里面的font-family: "iconfont";
                textAlign: 'center',
                textBaseline: 'middle',
                text: cfg.text,
                fontSize: cfg.size,
                ...style,
              },
              // must be assigned in G6 3.3 and later versions. it can be any value you want
              name: 'text-shape1',
            });
            const labelY = backgroundStyle ? cfg.size * 2 : cfg.size;

            group.addShape('text', {
              attrs: {
                x: 0,
                y: labelY,
                textAlign: 'center',
                text: cfg.label,
                ...labelStyle.style,
              },
              // must be assigned in G6 3.3 and later versions. it can be any value you want
              name: 'text-shape1',
            });
            return keyShape;
          },
          getAnchorPoints () {
            return [
              [0, 0.5],
              [1, 0.5],
            ];
          },
        },
        'circle',
      );

      /*  G6.registerNode(
         'center-node',
         {
           afterDraw (cfg, group) {
             const r = cfg.size / 2;
             // group.addShape('circle', {
             //   zIndex: -3,
             //   attrs: {
             //     x: 0,
             //     y: 0,
             //     r: r + 10,
             //     fill: 'gray',
             //     opacity: 0.4,
             //   },
             //   name: 'circle-shape1',
             // });
             // group.addShape('circle', {
             //   zIndex: -2,
             //   attrs: {
             //     x: 0,
             //     y: 0,
             //     r: r + 20,
             //     fill: 'gray',
             //     opacity: 0.2,
             //   },
             //   name: 'circle-shape2',
             // });
             group.sort();
           },
           getAnchorPoints () {
             return [
               [0, 0.5],
               [1, 0.5],
             ];
           },
         },
         'circle',
       ); */
      //使用iconfont
      G6.registerNode('iconfont', {
        draw (cfg, group) {
          const { backgroundConfig: backgroundStyle, style, labelCfg: labelStyle } = cfg;

          if (backgroundStyle) {
            group.addShape('circle', {
              attrs: {
                x: 0,
                y: 0,
                r: cfg.size,
                ...backgroundStyle,
              },
              // must be assigned in G6 3.3 and later versions. it can be any value you want
              name: 'circle-shape',
            });
          }
          group.addShape('circle', {
            attrs: {
              x: -12,
              y: 0,
              r: 30,
              ...backgroundStyle,
            },
            name: 'circle-shape',
          });
          const keyShape = group.addShape('text', {
            attrs: {
              x: 0,
              y: 0,
              fontFamily: 'iconfont', // 对应css里面的font-family: "iconfont";
              textAlign: 'center',
              textBaseline: 'middle',
              text: cfg.text,
              fontSize: cfg.size,
              ...style,
            },
            // must be assigned in G6 3.3 and later versions. it can be any value you want
            name: 'text-shape1',
          });
          const labelY = backgroundStyle ? cfg.size * 2 : cfg.size;

          group.addShape('text', {
            attrs: {
              x: 0,
              y: labelY,
              textAlign: 'center',
              text: cfg.label,
              ...labelStyle.style,
            },
            // must be assigned in G6 3.3 and later versions. it can be any value you want
            name: 'text-shape1',
          });
          return keyShape;
        },
      });
      // lineDash 的差值，可以在后面提供 util 方法自动计算
      const dashArray = [
        [0, 1],
        [0, 2],
        [1, 2],
        [0, 1, 1, 2],
        [0, 2, 1, 2],
        [1, 2, 1, 2],
        [2, 2, 1, 2],
        [3, 2, 1, 2],
        [4, 2, 1, 2],
      ];
      const lineDash = [4, 2, 1, 2];
      const interval = 9;

      G6.registerEdge(
        'can-running',
        {
          setState (name, value, item) {
            const shape = item.get('keyShape');
            if (name === 'running') {
              if (value) {
                const length = shape.getTotalLength(); // 后续 G 增加 totalLength 的接口
                let totalArray = [];
                for (let i = 0; i < length; i += interval) {
                  totalArray = totalArray.concat(lineDash);
                }
                let index = 0;
                shape.animate(
                  () => {
                    const cfg = {
                      lineDash: dashArray[index].concat(totalArray),
                    };
                    index = (index + 1) % interval;
                    return cfg;
                  },
                  {
                    repeat: true,
                    duration: 3000,
                  },
                );
              } else {
                shape.stopAnimate();
                shape.attr('lineDash', null);
              }
            }
          },
        },
        'cubic-horizontal',
      );

      G6.registerEdge(
        'line-dash',
        {
          afterDraw (cfg, group) {
            // 获得该边的第一个图形，这里是边的 path
            const shape = group.get('children')[0];
            // 获得边的 path 的总长度
            const length = shape.getTotalLength();
            let totalArray = [];
            // 计算出整条线的 lineDash
            for (let i = 0; i < length; i += interval) {
              totalArray = totalArray.concat(lineDash);
            }

            let index = 0;
            // 边 path 图形的动画
            shape.animate(
              () => {
                // 每一帧的操作，入参 ratio：这一帧的比例值（Number）。返回值：这一帧需要变化的参数集（Object）。
                const cfg = {
                  lineDash: dashArray[index].concat(totalArray),
                };
                // 每次移动 1
                index = (index + 1) % interval;
                // 返回需要修改的参数集，这里只修改了 lineDash
                return cfg;
              },
              {
                repeat: true, // 动画重复
                duration: 3000, // 一次动画的时长为 3000
              },
            );
          },
          /* setState (name, value, item) {
            const shape = item.get('keyShape');
            if (name === 'defaultRunning') {
              if (value) {
                // 获得该边的第一个图形，这里是边的 path
                // 获得当前边的第一个图形，这里是边本身的 path
                const shape = group.get('children')[0];
                // 边 path 的起点位置
                const startPoint = shape.getPoint(0);

                // 添加红色 circle 图形
                const circle = group.addShape('circle', {
                  attrs: {
                    x: startPoint.x,
                    y: startPoint.y,
                    fill: '#1890ff',
                    r: 3,
                  },
                  name: 'circle-shape',
                });

                // 对红色圆点添加动画
                circle.animate(
                  ratio => {
                    // 每一帧的操作，入参 ratio：这一帧的比例值（Number）。返回值：这一帧需要变化的参数集（Object）。
                    // 根据比例值，获得在边 path 上对应比例的位置。
                    const tmpPoint = shape.getPoint(ratio);
                    // 返回需要变化的参数集，这里返回了位置 x 和 y
                    return {
                      x: tmpPoint.x,
                      y: tmpPoint.y,
                    };
                  },
                  {
                    repeat: true, // 动画重复
                    duration: 3000, // 一次动画的时间长度
                  },
                )
              } else {
                shape.stopAnimate();
                shape.attr('lineDash', null);
              }
            }
          } */
        },
        'cubic',
      );
      //线从无到有
      G6.registerEdge(
        'line-growth',
        {
          afterDraw (cfg, group) {
            // console.log(cfg)
            // console.log(group)
            const shape = group.get('children')[0];
            const length = shape.getTotalLength();
            shape.animate(
              ratio => {
                // 每一帧的操作，入参 ratio：这一帧的比例值（Number）。返回值：这一帧需要变化的参数集（Object）。
                const startLen = ratio * length;
                // 计算线的lineDash
                const cfg = {
                  lineDash: [startLen, length - startLen],
                };
                return cfg;
              },
              {
                repeat: true, // 动画重复
                duration: 2000, // 一次动画的时长为 2000
              },
            );
          },
        },
        'cubic-horizontal',
      );

      let COLOR = '#40a9ff'
      const width = document.getElementById('container').scrollWidth * 0.7;
      const height = document.getElementById('container').scrollHeight || 600;
      const graph = new G6.Graph({
        container: 'container',
        width,
        height,
        renderer: 'svg',
        modes: {
          default: [
            'drag-canvas',
            'drag-node',
            // 'collapse-expand',  //此属性树图专有，普通图会报错
            'zoom-canvas'
          ]
        },
        defaultNode: {
          backgroundConfig: {
            backgroundType: 'circle',
            fill: COLOR,
            stroke: 'LightSkyBlue',
          },
          type: 'iconfont',
          size: 12,
          style: {
            fill: '#DEE9FF',
            stroke: '#5B8FF9',
          },
          labelCfg: {
            style: {
              fill: COLOR,
              fontSize: 12,
            },
          },
          // linkPoints: {
          //   top: true,
          //   bottom: true,
          //   left: true,
          //   right: true,
          //   fill: 'black',
          //   size: 55,
          // },
        },
        defaultEdge: {
          // type: 'line-dash',
          // type: 'can-running',
          style: {
            stroke: '#b5b5b5',
            // fill: '#DEE9FF',
          },
        },
      });

      graph.data({ nodes, edges });
      graph.render();
      graph.fitView();
      // graph.setItemState(edge, 'defaultRunning', true);
      // 响应 hover 状态
      graph.on('node:mouseenter', ev => {
        const node = ev.item;
        const edges = node.getEdges();
        // console.log(ev)
        // console.log(node)
        // console.log(edges)
        edges.forEach(edge => graph.setItemState(edge, 'running', true));
      });
      graph.on('node:mouseleave', ev => {
        const node = ev.item;
        const edges = node.getEdges();
        edges.forEach(edge => graph.setItemState(edge, 'running', false));
      });

      // graph.findAll('edge', edge => {
      //   console.log(edge)
      // })
      // let alledge = graph.getEdges()
      // console.log(alledge)

      let model = {
        type: 'can-running',
        text: '\ue60e',
        style: {
          stroke: 'yellow'
        },
        labelCfg: {
          style: {
            fill: 'cyan'
          }
        },
      };

      // 通过 ID 查询节点实例
      /* const item = graph.findById('edge10');
      const item2 = graph.findById('edge11');
      const item3 = graph.findById('edge12');
      const item4 = graph.findById('edge13');
      const item5 = graph.findById('edge14'); */
      //增加edge的标识id字段后
      const item = graph.findById('edgeRight0');
      const item2 = graph.findById('edgeRight1');
      const item3 = graph.findById('edgeRight2');
      const item4 = graph.findById('edgeRight3');
      const item5 = graph.findById('edgeRight4');
      setInterval(() => {
        model.labelCfg.style.fill = this.getRandomColor()
        model.style.stroke = this.getRandomColor()
        graph.updateItem(item, model);
        graph.updateItem(item2, model);
        graph.updateItem(item3, model);
        graph.updateItem(item4, model);
        graph.updateItem(item5, model);
      }, 1000);
    },
    getRandomColor () {
      var rand = Math.floor(Math.random() * 0xFFFFFF).toString(16);
      if (rand.length == 6) {
        return '#' + rand;
      } else {
        return this.getRandomColor();
      }
    }
  }
}

</script>

<style scoped>
</style>